package org.luxor.eshop.payment.service.impl;

import io.seata.spring.annotation.GlobalTransactional;
import org.luxor.commons.core.exception.TransactionException;
import org.luxor.commons.core.utils.IdWorker;
import org.luxor.eshop.payment.entity.dto.OrderDto;
import org.luxor.eshop.payment.entity.dto.PaymentReqDto;
import org.luxor.eshop.payment.entity.dto.ReceiptReqDto;
import org.luxor.eshop.payment.entity.dto.TransferDto;
import org.luxor.eshop.payment.service.AccountFeign;
import org.luxor.eshop.payment.service.OrderFeign;
import org.luxor.eshop.payment.service.PaymentService;
import org.luxor.eshop.payment.service.TransferTccAction;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * 在线支付服务
 *
 * @author Mr.Yan  @date: 2020/11/25
 */
@Service
public class PaymentServiceImpl implements PaymentService {

    private final static String RECEIPT_ACCOUNT = "admin";

    @Resource
    private OrderFeign orderFeign;
    @Resource
    private AccountFeign accountFeign;
    @Resource
    private TransferTccAction transferTccAction;

    /**
     * 订单支付
     */
    @Override
    public void orderPayment(Long orderId) {
        // 获取订单信息
        OrderDto orderInfo = orderFeign.get(orderId).assertSuccess().getData();

        // 转账交易
        TransferDto transfer = new TransferDto();
        transfer.setPaymentAccount(orderInfo.getAccount());
        transfer.setReceiptAccount(RECEIPT_ACCOUNT);
        transfer.setAmounts(orderInfo.getMoney());
        this.transfer(transfer);
    }

    /**
     * 转账交易 (TCC模式)
     */
    @Override
    @GlobalTransactional(rollbackFor = TransactionException.class)
    public void transfer(TransferDto transfer) {
        // 生成全局唯一的账单编号
        Long billCode = IdWorker.getId();

        // 发起转帐交易 (TCC事务发起者)
        transferTccAction.prepare(null,
                billCode,
                transfer.getOrderId(),
                transfer.getPaymentAccount(),
                transfer.getReceiptAccount(),
                transfer.getAmounts());

        // 买家付款 (第一个TCC事务参与者)
        PaymentReqDto paymentReq = new PaymentReqDto();
        paymentReq.setBillCode(billCode);
        paymentReq.setPaymentAccount(transfer.getPaymentAccount());
        paymentReq.setAmounts(transfer.getAmounts());
        accountFeign.payment(paymentReq);

        // 买家收款 (第二个TCC事务参与者)
        ReceiptReqDto receiptReq = new ReceiptReqDto();
        receiptReq.setBillCode(billCode);
        receiptReq.setReceiptAccount(transfer.getReceiptAccount());
        receiptReq.setAmounts(transfer.getAmounts());
        accountFeign.receipt(receiptReq);
    }
}
